home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------------------------------;
- ; HOOKINTS.ASM ;
- ; ;
- ; Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits. ;
- ; Redistributed by permission. ;
- ;-----------------------------------------------------------------------;
- % .MODEL memmodel,c
-
- EXTRN atexit:PROC
- EXTRN messagebox:PROC,sprintf:PROC
-
- .DATA
- IF @CodeSize
- EXTRN _PL_helpfunc:FAR PTR
- old_helpfunc DD 0
- ELSE
- EXTRN _PL_helpfunc:NEAR PTR
- old_helpfunc DW 0
- ENDIF
-
- PUBLIC _PL_breakflag
- _PL_breakflag DW 0
-
- installed_flag DB 0 ;1 = handler is installed
- registered_flag DB 0 ;1 = unhookints registered w/atexit
-
- IF @DataSize ;Pointer to COLORSTRUCT for
- error_colors DD 0 ; messagebox()
- ELSE
- error_colors DW 0
- ENDIF
-
- MB_RETRYABORT EQU 03h ;messagebox() flags
- MAX_ERRORNUM EQU 0Ch
- error_00h DB "Attempted to write to write-protected disk",0
- error_01h DB "Unknown unit (invalid drive number)",0
- error_02h DB "Drive not ready (no diskette or drive door is open)",0
- error_03h DB "Unknown command requested",0
- error_04h DB "Data error (CRC)",0
- error_05h DB "Length of requested structure invalid",0
- error_06h DB "Seek error (move to requested cylinder failed)",0
- error_07h DB "Non-MS-DOS disk",0
- error_08h DB "Sector not found",0
- error_09h DB "Printer out of paper",0
- error_0Ah DB "Write fault",0
- error_0Bh DB "Read fault",0
- error_0Ch DB "General fault",0
-
- error_table LABEL WORD
- DW OFFSET error_00h,OFFSET error_01h,OFFSET error_02h
- DW OFFSET error_03h,OFFSET error_04h,OFFSET error_05h
- DW OFFSET error_06h,OFFSET error_07h,OFFSET error_08h
- DW OFFSET error_09h,OFFSET error_0Ah,OFFSET error_0Bh
- DW OFFSET error_0Ch
-
- error_format DB "%s",0Ah,"%s",0
- error_title DB "Error",0
- device_error DB "Device error",0
- disk_error DB "Error on drive "
- drive DB "A:",0
- buffer DB 128 DUP (?)
-
- old1B_handler DD 0 ;Storage for old interrupt handlers
- old23_handler DD 0
- old24_handler DD 0
-
-
- .CODE
- ;-----------------------------------------------------------------------;
- ; Ctrl-break interrupt hander. ;
- ; ;
- ; Usage: This procedure cannot be called directly from C. ;
- ;-----------------------------------------------------------------------;
- IFDEF ??version ;Turbo Assembler
- int1B_handler PROC FAR
- ELSE
- int1B_handler PROC FAR PRIVATE
- ENDIF
- sti
- push ax
- push es
- mov ax,0040h
- mov es,ax
- and BYTE PTR es:[0071h],NOT 80h
- mov ax,@Data
- mov es,ax
- mov es:_PL_breakflag,1 ;Set break flag
- pop es
- pop ax
- iret
- int1B_handler ENDP
-
- ;-----------------------------------------------------------------------;
- ; Ctrl-C interrupt handler. ;
- ; ;
- ; Usage: This procedure cannot be called directly from C. ;
- ;-----------------------------------------------------------------------;
- IFDEF ??version ;Turbo Assembler
- int23_handler PROC FAR
- ELSE
- int23_handler PROC FAR PRIVATE
- ENDIF
- iret
- int23_handler ENDP
-
- ;-----------------------------------------------------------------------;
- ; This procedure becomes the new critical-error interrupt handler. This ;
- ; handler disables help by setting int (*_PL_helpfunc)() to NULL. Help ;
- ; must never be called from within an interrupt! ;
- ; ;
- ; Usage: This procedure cannot be called directly from C. ;
- ;-----------------------------------------------------------------------;
- IFDEF ??version ;Turbo Assembler
- int24_handler PROC FAR
- ELSE
- int24_handler PROC FAR PRIVATE
- ENDIF
- sti
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
- mov dx,@Data ;ds = data segment
- mov ds,dx
- IF @CodeSize
- mov bx,WORD PTR _PL_helpfunc[0]
- mov WORD PTR old_helpfunc[0],bx
- mov bx,WORD PTR _PL_helpfunc[2]
- mov WORD PTR old_helpfunc[2],bx
- mov WORD PTR _PL_helpfunc[0],0
- mov WORD PTR _PL_helpfunc[2],0
- ELSE
- mov bx,_PL_helpfunc
- mov old_helpfunc,bx
- mov _PL_helpfunc,0
- ENDIF
- test ah,80h ;Was the error disk-related?
- jnz not_disk_error ;No
- add al,'A' ;Else set drive letter
- mov drive,al
- mov dx,OFFSET disk_error ;Disk error message
- jmp err_type_ready
- not_disk_error:
- mov dx,OFFSET device_error ;Device error message
- err_type_ready:
- mov bx,di ;Error code
- sub bh,bh
- cmp bx,MAX_ERRORNUM
- jna good_errornum
- mov bx,MAX_ERRORNUM
- good_errornum:
- shl bx,1
- add bx,OFFSET error_table
- mov bx,[bx]
- IF @DataSize ;sprintf(buffer,format,dx,bx);
- push ds
- push bx
- push ds
- push dx
- push ds
- mov ax,OFFSET error_format
- push ax
- push ds
- mov ax,OFFSET buffer
- push ax
- ELSE
- push bx
- push dx
- mov ax,OFFSET error_format
- push ax
- mov ax,OFFSET buffer
- push ax
- ENDIF
- call sprintf
- IF @DataSize
- add sp,16
- ELSE
- add sp,8
- ENDIF
- IF @DataSize ;messagebox(msg,wtitle,flags,&colors);
- push WORD PTR error_colors[2]
- push WORD PTR error_colors[0]
- mov ax,MB_RETRYABORT
- push ax
- push ds
- mov ax,OFFSET error_title
- push ax
- push ds
- mov ax,OFFSET buffer
- push ax
- ELSE
- push error_colors
- mov ax,MB_RETRYABORT
- push ax
- mov ax,OFFSET error_title
- push ax
- mov ax,OFFSET buffer
- push ax
- ENDIF
- call messagebox
- IF @DataSize
- add sp,14
- ELSE
- add sp,8
- ENDIF
- IF @CodeSize
- mov bx,WORD PTR old_helpfunc[0]
- mov WORD PTR _PL_helpfunc[0],bx
- mov bx,WORD PTR old_helpfunc[2]
- mov WORD PTR _PL_helpfunc[2],bx
- ELSE
- mov bx,old_helpfunc
- mov _PL_helpfunc,bx
- ENDIF
- cmp ax,01h ;Did user give 'retry' response?
- je end_int24_handler ;Yes
- mov ax,03h ;Else fail current system call
- end_int24_handler:
- pop es
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- iret
- int24_handler ENDP
-
- PUBLIC unhookints
- ;-----------------------------------------------------------------------;
- ; Removes the interrupt handlers installed by hookints and re-installs ;
- ; the original interrupt vectors. ;
- ; ;
- ; Usage: int unhookints(void); ;
- ; Returns: 0 = success, -1 = error ;
- ;-----------------------------------------------------------------------;
- unhookints PROC
- mov ax,-1 ;Return error if our handlers
- cmp installed_flag,0 ; are not installed
- je end_unhookints
- push ds ;Preserve ds
- push ds ;Use es to access data segment
- pop es
- mov ax,251Bh ;Restore original interrupt 1Bh
- lds dx,es:old1B_handler ; vector
- int 21h
- mov ax,2523h ;Restore original interrupt 23h
- lds dx,es:old23_handler ; vector
- int 21h
- mov ax,2524h ;Restore original interrupt 24h
- lds dx,es:old24_handler ; vector
- int 21h
- pop ds
- mov installed_flag,0 ;Indicate we're no longer installed
- sub ax,ax
- end_unhookints:
- ret
- unhookints ENDP
-
- PUBLIC hookints
- ;-----------------------------------------------------------------------;
- ; Installs custom interrupt handlers for Ctrl-C, Ctrl-break and ;
- ; critical error interrupts, and registers unhookints with atexit. ;
- ; colors argument specifies color used by messagebox for critical ;
- ; errors. ;
- ; ;
- ; Usage: int hookints(COLORSTRUCT *colors); ;
- ; Returns: 0 = success, -1 = error. ;
- ;-----------------------------------------------------------------------;
- hookints PROC colors:PTR BYTE
- mov ax,-1 ;Return error if we're already
- cmp installed_flag,1 ; installed
- jne not_installed
- jmp end_hookints
- not_installed:
- IF @DataSize
- mov ax,WORD PTR colors[0]
- mov WORD PTR error_colors[0],ax
- mov ax,WORD PTR colors[2]
- mov WORD PTR error_colors[2],ax
- ELSE
- mov ax,colors
- mov error_colors,ax
- ENDIF
- mov ax,351Bh ;Get old interrupt 1Bh vector
- int 21h
- mov WORD PTR old1B_handler[0],bx
- mov WORD PTR old1B_handler[2],es
- push ds ;Set new interrupt 1Bh vector
- mov ax,251Bh
- push cs
- pop ds
- mov dx,OFFSET int1B_handler
- int 21h
- pop ds
- mov ax,3523h ;Get old interrupt 23h vector
- int 21h
- mov WORD PTR old23_handler[0],bx
- mov WORD PTR old23_handler[2],es
- push ds ;Set new interrupt 23h vector
- mov ax,2523h
- push cs
- pop ds
- mov dx,OFFSET int23_handler
- int 21h
- pop ds
- mov ax,3524h ;Get old interrupt 24h vector
- int 21h
- mov WORD PTR old24_handler[0],bx
- mov WORD PTR old24_handler[2],es
- push ds ;Set new interrupt 24h vector
- mov ax,2524h
- push cs
- pop ds
- mov dx,OFFSET int24_handler
- int 21h
- pop ds
- mov installed_flag,1 ;Indicate we're installed
- mov ax,0
- cmp registered_flag,1 ;Are we already registered w/atexit?
- je end_hookints ;Yes, done
- mov registered_flag,1
- IF @CodeSize ;atexit(unhookints)
- push cs
- mov ax,OFFSET unhookints
- push ax
- ELSE
- mov ax,OFFSET unhookints
- push ax
- ENDIF
- call atexit
- IF @CodeSize
- add sp,4
- ELSE
- inc sp
- inc sp
- ENDIF
- or ax,ax ;Was atexit() successful?
- jz end_hookints ;Yes, return 0
- call unhookints ;Else uninstall handler
- mov registered_flag,0
- mov ax,-1 ;Return error
- end_hookints:
- ret
- hookints ENDP
-
- END
-